package com.wechat.wins.http;

import javax.net.ssl.SSLEngine;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.ssl.SslHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpsServerImpl extends HttpsBase implements HttpsServer {

    private final Logger logger = LoggerFactory.getLogger(HttpsServerImpl.class);

    public HttpsServerImpl(final int port) {
        final EventLoopGroup master = new NioEventLoopGroup();
        final EventLoopGroup worker = new NioEventLoopGroup();
        final ServerBootstrap server = new ServerBootstrap();
        try {
            server.channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .group(master, worker)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(final SocketChannel channel) throws Exception {
                            final SSLEngine sslEngine = SSLContextFactory.getSSLContext().createSSLEngine();
                            sslEngine.setUseClientMode(false);
                            final ChannelPipeline pip = channel.pipeline();
                            pip.addFirst(new SslHandler(sslEngine));
                            pip.addLast("codec", new HttpServerCodec());
                            pip.addLast(new HttpObjectAggregator(512 * 1204));
                            pip.addLast(new HttpsServerHandler());
                        }

                    });
            final ChannelFuture future = server.bind(port).sync();
            future.channel().closeFuture().sync();
        } catch (final InterruptedException e) {
            this.logger.error("Happened Error!", e);
            e.printStackTrace();
        } finally {
            master.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }

    @Override
    public void start() {

    }
}
